#include "TCP_Master.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#include "../connectionManger/connectionManger.h"
#include "../memoryPool/e_palloc.h"
#include "../threadPool/thread_pool.h"

#define DEBUG 1
// 全局连接池实例
extern ConnectionManger m_conn_manager;
extern ThreadPool *m_thread_pool;
extern struct mp_pool_s *m_mp;
int Init_tcp_server(){
    int server_fd, epoll_fd;
    struct sockaddr_in addr;
    struct epoll_event ev, events[MAX_EVENTS];

    // 创建TCP socket
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }

    // 设置地址重用
    int opt = 1;
    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(PORT);

    // 绑定socket
    if (bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        perror("bind failed");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

    // 设置非阻塞模式
    set_nonblocking(server_fd);

    // 开始监听
    if (listen(server_fd, SOMAXCONN) < 0) {
        perror("listen failed");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

    // 创建epoll实例
    if ((epoll_fd = epoll_create1(0)) < 0) {
        perror("epoll creation failed");
        close(server_fd);
        exit(EXIT_FAILURE);
    }



    // 添加服务器socket到epoll
    ev.events = EPOLLIN | EPOLLET; // 边缘触发模式
    ev.data.fd = server_fd;
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &ev) < 0) {
        perror("epoll_ctl failed");
        close(server_fd);
        close(epoll_fd);
        exit(EXIT_FAILURE);
    }

    printf("Server started on port %d\n", PORT);

    while (1) {
        static time_t last_check = 0;
        time_t now = time(NULL);
        if(now - last_check >= 500){
            connection_check_timeout();
            last_check = now;
        }
        int nready = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
        if (nready < 0) {
            perror("epoll_wait error");
            continue;
        }

        for (int i = 0; i < nready; i++) {
            if (events[i].data.fd == server_fd) {
                printf("accepting new socket\n");
                accept_new_sock(epoll_fd, server_fd);
            }
            else{
                DeviceContext *ctx = (DeviceContext *) events[i].data.ptr;
                if (events[i].events & (EPOLLERR | EPOLLRDHUP | EPOLLHUP)) {
                    handle_disconnect(ctx, epoll_fd);
                } else if (events[i].events & EPOLLIN) {
                    handle_read(ctx, epoll_fd);
                }
            }
        }
    }

    close(server_fd);
    close(epoll_fd);
    return 0;
}


int set_nonblocking(int fd) {
    int flags = fcntl(fd, F_GETFL, 0);
    return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}

int handle_read(DeviceContext *ctx,int epoll_fd){
    RCV_DATA_TYPE buffer[1024];
    ssize_t n;
    while(1) {
        n = read(ctx->sock_fd,buffer,sizeof(buffer));
        if(n > 0) {
            //绑定字符串,需要考虑数据分为多次传达时的数据拼接。
            memcpy(ctx->rcv_data,buffer,n);
            ctx->rcv_len = n;
            printf("\n");
        } else if(n == 0){
            epoll_ctl(epoll_fd, EPOLL_CTL_DEL, ctx->sock_fd, NULL);
            close(ctx->sock_fd);
            // 从链表移除...
            mp_free(m_mp,ctx);
            break;
        } else{
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                // 非阻塞情况下读完了
                break;
            } else {
                // 其他错误
                perror("read error");
                close(ctx->sock_fd);
                mp_free(m_mp,ctx);
                break;
            }

        }
    }

    //当数据获取完毕时，执行数据处理
#if DEBUG
    printf("received %zd bytes on fd: %d, data: ", n, ctx->sock_fd);
    for (ssize_t i = 0; i < n; i++) {
        printf("%02x ", buffer[i]); // 以两位十六进制格式打印每个字节
    }
    printf("\n");
#endif

    // 检查绑定状态
    if(ctx->state == DEVICE_STATE_UNREGISTERED) {
        bind_device(ctx);
    } else {
        // 处理已绑定设备数据
        if (m_thread_pool) {
            thread_pool_add_task(m_thread_pool,process_task,ctx);
        }else {
            process_device_data(ctx);
        }
    }
    return 0;
}

int handle_disconnect(DeviceContext *ctx,int epoll_fd){
    printf("Client disconnected: fd=%d\n", ctx->sock_fd);
    epoll_ctl(epoll_fd, EPOLL_CTL_DEL, ctx->sock_fd, NULL);
    close(ctx->sock_fd);
    //通过fd找到connection
    Connection *conn = connection_find_by_fd(ctx->sock_fd);
    if (conn) {
        //释放整个connection对象
        connection_release(conn);
    }
    return 0;
}

int accept_new_sock(int epoll_fd, int server_fd) {
    while (1) {
        struct sockaddr_in client_addr;
        socklen_t addr_len = sizeof(client_addr);
        int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &addr_len);
        if (client_fd < 0) {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                break; // 已经没有可接受的连接了
            } else {
                perror("accept error");
                return -1;
            }
        }

        set_nonblocking(client_fd);

        Connection *conn = connection_acquire(client_fd);

        if (!conn) {
            perror("Failed acquire new connection");
            close(client_fd);
            continue;
        }

        struct epoll_event ev;
        ev.events = EPOLLIN | EPOLLET | EPOLLRDHUP;
        ev.data.ptr = conn->devcie_ctx;

        if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &ev) < 0) {
            perror("epoll_ctl client error");
            close(client_fd);
            mp_free(m_mp,conn->devcie_ctx);
            continue;
        }
    }
    printf("new client connect\n");
    return 0;
}

int bind_device(DeviceContext *ctx){
    //ctx->register_code  寻找表中的设备与buf相符合，如果符合则绑定设备，绑定dev->ctx->fd
    ctx->state = DEVICE_STATE_REGISTERED;
    printf("first connected,bind with device\n");
    thread_pool_add_task(m_thread_pool,process_task,ctx);
    return 0;
}
int process_device_data(DeviceContext *ctx){
    size_t i;
    printf(" receive socket_fd: %d data:  ",ctx->sock_fd);
    for (i = 0 ;  i < ctx->rcv_len ; i++){
        printf(" receive data:%02x  ",ctx->rcv_data[i]);
    }
    printf("\n");

    ssize_t bytes_sent = write(ctx->sock_fd, ctx->rcv_data, ctx->rcv_len);
    if (bytes_sent < 0) {
        perror("write error");
        return -1;
    }

    // 更新连接统计信息
    Connection* conn = connection_find_by_fd(ctx->sock_fd);
    if (conn) {
        connection_update_stats(conn, ctx->rcv_len, bytes_sent);
    }

    return 0;
}

void process_task(void *arg) {
    DeviceContext *ctx = (DeviceContext *)arg;
    if (!ctx) return;

    // 这里的逻辑和之前的 process_device_data 类似
    printf("Thread pool processing data for fd %d\n", ctx->sock_fd);
#if DEBUG
    printf("write %zd bytes on fd: %d, data: ", ctx->rcv_len, ctx->sock_fd);
    for (ssize_t i = 0; i < ctx->rcv_len; i++) {
        printf("%02x ", ctx->rcv_data[i]); // 以两位十六进制格式打印每个字节
    }
    printf("\n");
#endif
    ssize_t bytes_sent = write(ctx->sock_fd, ctx->rcv_data, ctx->rcv_len);
    if (bytes_sent < 0) {
        perror("write error in thread");
    }

    Connection* conn = connection_find_by_fd(ctx->sock_fd);
    if (conn) {
        connection_update_stats(conn, ctx->rcv_len, bytes_sent);
    }

    // 注意：由于ctx是从epoll传递过来的，它的生命周期需要小心管理。
    // 在这个简单模型中，我们假设在连接断开前ctx都有效。
}
